﻿using Backload.Controllers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Backload;
using System.Threading.Tasks;
using Backload.Plugin.Handler;
using System.Threading;
using Dapper;
using LibMS.Models;
using System.Web.Hosting;

namespace LibMS.Controllers
{
    [Authorize(Roles = "System Admin, Lib Admin")]
    public class FileUploadController : Controller
    {
        private readonly UnitOfWork _unitOfWork = new UnitOfWork();
        private int _documentId = 0;

        public async Task<ActionResult> FileHandler(int documentId)
        {            
            _documentId = documentId;
            FileUploadHandler handler = new FileUploadHandler(Request, this);
            //handler.IncomingRequestStarted += handler_IncomingRequestStarted;

            //handler.AuthorizeRequestStarted += handler_AuthorizeRequestStarted;
            //handler.AuthorizeRequestFinished += handler_AuthorizeRequestFinished;

            handler.GetFilesRequestStarted += handler_GetFilesRequestStarted;
            //handler.GetFilesRequestFinished += handler_GetFilesRequestFinished;
            //handler.GetFilesRequestException += handler_GetFilesRequestException;

            handler.StoreFileRequestStartedAsync += handler_StoreFileRequestStartedAsync; // async event handler 
            handler.StoreFileRequestFinished += handler_StoreFileRequestFinished;
            handler.StoreFileRequestException += handler_StoreFileRequestException;

            //handler.DeleteFilesRequestStarted += handler_DeleteFilesRequestStarted;
            handler.DeleteFilesRequestFinishedAsync += handler_DeleteFilesRequestFinishedAsync; // async event handler 
            handler.DeleteFilesRequestException += handler_DeleteFilesRequestException;

            //handler.OutgoingResponseCreated += handler_OutgoingResponseCreated;

            //handler.ProcessPipelineExceptionOccured += handler_ProcessPipelineExceptionOccured;

            ActionResult result = await handler.HandleRequestAsync();
            return result;
        }

        void handler_GetFilesRequestStarted(object sender, Backload.Eventing.Args.GetFilesRequestEventArgs e)
        {
            e.Param.BackloadValues.FilesFilter = "*." + _documentId + ".*";
        }

        async Task handler_StoreFileRequestStartedAsync(object sender, Backload.Eventing.Args.StoreFileRequestEventArgs e)
        {
            var fileExtension = e.Param.FileStatusItem.FileName.Split(new []{'.'}).LastOrDefault();
            var newFileName = (!string.IsNullOrEmpty(fileExtension) && !fileExtension.Equals(e.Param.FileStatusItem.FileName)) ? e.Param.FileStatusItem.FileName.Replace(fileExtension, _documentId + "." + fileExtension) : string.Format("{0}.{1}.n", e.Param.FileStatusItem.FileName, _documentId);
            var urlFileName = e.Param.FileStatusItem.DeleteUrl.Substring(e.Param.FileStatusItem.DeleteUrl.IndexOf("fileName") + 9);
            var newUrlFileName = urlFileName.Split(new[] { '.' }).First() + "." + _documentId;

            e.Param.FileStatusItem.DeleteUrl = e.Param.FileStatusItem.DeleteUrl.Replace(urlFileName.Split(new[] { '.' }).First(), newUrlFileName);
            e.Param.FileStatusItem.FileUrl = e.Param.FileStatusItem.FileUrl.Replace(urlFileName.Split(new[] { '.' }).First(), newUrlFileName);
            e.Param.FileStatusItem.ThumbnailUrl = e.Param.FileStatusItem.ThumbnailUrl.Replace(urlFileName.Split(new[] { '.' }).First(), newUrlFileName);
            e.Param.FileStatusItem.StorageInfo.FilePath = e.Param.FileStatusItem.StorageInfo.FilePath.Replace(e.Param.FileStatusItem.FileName, newFileName);
            e.Param.FileStatusItem.StorageInfo.MappingsPath = e.Param.FileStatusItem.StorageInfo.MappingsPath.Replace(e.Param.FileStatusItem.FileName, newFileName);
            e.Param.FileStatusItem.StorageInfo.ThumbnailPath = e.Param.FileStatusItem.StorageInfo.ThumbnailPath.Replace(e.Param.FileStatusItem.FileName, newFileName);
            e.Param.FileStatusItem.OriginalName = newFileName;
            e.Param.FileStatusItem.ThumbnailName = e.Param.FileStatusItem.ThumbnailName.Replace(e.Param.FileStatusItem.FileName, newFileName);
            e.Param.FileStatusItem.FileName = newFileName;
        }

        void handler_StoreFileRequestFinished(object sender, Backload.Eventing.Args.StoreFileRequestEventArgs e)
        {
            if (System.IO.File.Exists(e.Param.FileStatusItem.StorageInfo.FilePath))
            {                
                string message;
                var parameters = new DynamicParameters();
                parameters.Add("@DocumentId", _documentId);
                parameters.Add("@FileName", e.Param.FileStatusItem.FileName);
                parameters.Add("@FileExtension", e.Param.FileStatusItem.FileName.Contains('.') ? e.Param.FileStatusItem.FileName.Split(new []{'.'}).LastOrDefault() : null);
                parameters.Add("@FilePath", e.Param.FileStatusItem.StorageInfo.FileDirectoryUrl.LocalPath + e.Param.FileStatusItem.FileName);
                var data = _unitOfWork.LibUploadData.Create(out message, parameters);
            }
            else
            {
                e.Param.FileStatusItem.Success = false;
            }
        }

        void handler_StoreFileRequestException(object sender, Backload.Eventing.Args.StoreFileRequestEventArgs e)
        {
            if (e != null && !System.IO.File.Exists(e.Param.FileStatusItem.StorageInfo.FilePath))
            {
                string message;
                var parameters = new DynamicParameters();
                parameters.Add("@DocumentId", _documentId);
                parameters.Add("@FileName", e.Param.FileStatusItem.FileName);
                parameters.Add("@FileExtension", e.Param.FileStatusItem.FileName.Contains('.') ? e.Param.FileStatusItem.FileName.Split(new[] { '.' }).LastOrDefault() : null);
                var data = _unitOfWork.LibUploadData.Delete(out message, parameters);
            }
        }

        async Task handler_DeleteFilesRequestFinishedAsync(object sender, Backload.Eventing.Args.DeleteFilesRequestEventArgs e)
        {
            foreach (var file in e.Param.DeleteFiles.Files)
            {
                if (file.ErrorCode == 0 && !System.IO.File.Exists(file.StorageInfo.FilePath))
                {
                    string message;
                    var parameters = new DynamicParameters();
                    parameters.Add("@DocumentId", _documentId);
                    parameters.Add("@FileName", file.FileName);
                    parameters.Add("@FileExtension", file.FileName.Contains('.') ? file.FileName.Split(new[] { '.' }).LastOrDefault() : null);
                    var data = _unitOfWork.LibUploadData.Delete(out message, parameters);
                }
            }
        }

        void handler_DeleteFilesRequestException(object sender, Backload.Eventing.Args.DeleteFilesRequestEventArgs e)
        {

        }
    }
}
